package com.mspbots.sync.wise.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.mspbots.api.DataNotFoundException;
import com.mspbots.sync.BaseGenericService;
import com.mspbots.sync.model.ExceptionLog;
import com.mspbots.sync.model.ProjectPhaseOnly;
import com.mspbots.sync.utils.WiseParamsUtils;
import com.mspbots.sync.wise.client.ClientProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * com.mspbots.sync.wise.service.ProjectPhaseService
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/11/13
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class ProjectPhaseService extends BaseGenericService {

    public Flux<ProjectPhaseOnly> getProjectPhases(ClientProperties configuration) {
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        params.set("orderBy", "id");
        return this.cwWebClient.fetch("/project/projects/", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync project error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-project").msg("Connect wise sync project entry error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    return Flux.just(jsonNode);
                })
                .switchIfEmpty(Mono.error(new DataNotFoundException("This tenant " + configuration.getTenantId() + " get project is empty.")))
                .flatMap(proJsonNode -> this.getPhase(configuration, proJsonNode.get("id").asInt())
                        .map(jsonNode ->
                                ProjectPhaseOnly.builder()
                                        .tenantId(configuration.getTenantId())
                                        .cwId(jsonNode.get("id").asInt())
                                        .projectId(jsonNode.get("projectId").asInt())
                                        .name(jsonNode.get("description").asText())
                                        .boardId(jsonNode.get("board").get("id").asInt())
                                        .statusId(jsonNode.get("status").get("id").asInt())
                                        .extend(jsonNode)
                                        .build()
                        ));
    }

    public Flux<JsonNode> getPhase(ClientProperties configuration, Integer projectId) {
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        params.set("orderBy", "id");
        return this.cwWebClient.fetch("/project/projects/" + projectId + "/phases", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .defaultIfEmpty(this.objectMapper.createObjectNode());
    }
}
